package com.dhcc.core.framework.cas;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.pac4j.core.profile.CommonProfile;

import com.dhcc.core.framework.constant.Const;
import com.dhcc.core.framework.constant.state.ManagerStatus;
import com.dhcc.core.framework.util.CommonUtil;
import com.dhcc.core.framework.util.SpringContextHolder;
import com.dhcc.core.modules.system.cache.permission.PermissionCache;
import com.dhcc.core.modules.system.cache.role.RoleCache;
import com.dhcc.core.modules.system.entity.User;
import com.dhcc.core.modules.system.service.IUserService;

import io.buji.pac4j.realm.Pac4jRealm;
import io.buji.pac4j.subject.Pac4jPrincipal;
import io.buji.pac4j.token.Pac4jToken;

/**
 * ShiroCasRealm
 * 
 * @ClassName: ShiroCasRealm
 * @Description: TODO
 * @author: cyf
 * @date: 2018年1月2日 上午10:00:28
 */
public class ShiroCasRealm extends Pac4jRealm {

    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
            throws AuthenticationException {
        final Pac4jToken pac4jToken = (Pac4jToken) authcToken;
        final List<CommonProfile> commonProfileList = pac4jToken.getProfiles();
        final CommonProfile commonProfile = commonProfileList.get(0); 
        System.out.println("单点登录返回的信息" + commonProfile.toString());
        final Pac4jPrincipal principal = new Pac4jPrincipal(commonProfileList, getPrincipalNameAttribute());
        String loginName = principal.getProfile().getId();
        IUserService userService = SpringContextHolder.getBean(IUserService.class);
        User user = userService.getByLoginName(loginName);
        // 账号不存在
        if (null == user) {
            throw new CredentialsException();
        }
        // 账号被冻结
        if (user.getStatus() != ManagerStatus.OK.getCode()) {
            throw new LockedAccountException();
        }
        // 填充用户部门角色信息
        user = user.fill();
        final PrincipalCollection principalCollection = new SimplePrincipalCollection(user, getName());
        return new SimpleAuthenticationInfo(principalCollection, commonProfileList.hashCode());
    }

    /**
     * 权限认证
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User) principals.getPrimaryPrincipal();
        Set<String> permissionSet = new HashSet<>();
        Set<String> roleCodes = new HashSet<>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            roleCodes.add(Const.ADMIN_NAME);
            roleCodes.add(Const.EVERYONE_NAME);
            permissionSet.add("*:*:*");
        } else {
            List<Long> roleIds = user.getRoleIds();
            roleIds.add(Const.EVERYONE_ROLE_ID);// everyone角色
            List<Long> deptIds = user.getDeptIds();

            // 角色的权限
            for (Long roleId : roleIds) {
                List<String> permissions = PermissionCache.me().findPermissionsByPrincipalId(roleId);
                if (permissions != null) {
                    for (String permission : permissions) {
                        if (CommonUtil.isNotEmpty(permission)) {
                            permissionSet.add(permission);
                        }
                    }
                }
                String roleCode = RoleCache.me().getRoleCodeById(roleId);
                roleCodes.add(roleCode);
            }
            // 部门的权限
            for (Long deptId : deptIds) {
                List<String> permissions = PermissionCache.me().findPermissionsByPrincipalId(deptId);
                if (permissions != null) {
                    for (String permission : permissions) {
                        if (CommonUtil.isNotEmpty(permission)) {
                            permissionSet.add(permission);
                        }
                    }
                }
            }
            // 用户个人的权限
            List<String> permissions = PermissionCache.me().findPermissionsByPrincipalId(user.getId());
            if (permissions != null) {
                for (String permission : permissions) {
                    if (CommonUtil.isNotEmpty(permission)) {
                        permissionSet.add(permission);
                    }
                }
            }
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(permissionSet);
        info.addRoles(roleCodes);
        return info;
    }
}
